package jenkins

import (
	"GoMaestro/internal/service"
	"github.com/gin-gonic/gin"
	"io"
	"sync"
)

type JenApi struct{}

// GetNodeStatus @Summary 查询Jenkins节点状态
// @Accept json
// @Produce json
// @Router /v1/jen/node/status [get]
func (*JenApi) GetNodeStatus(c *gin.Context) {
	status, err := service.AppJenServiceImp.GetNodeStatus()
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, gin.H{"data": status})
}

// GetBuildLog godoc
// @Summary 获取 jencli 构建日志
// @Description 根据 job 名称和构建 ID 获取构建日志
// @Param job path string true "Job 名称"
// @Param id path int true "构建 ID"
// @Success 200 {object} util.ResponseSuccess "成功返回构建日志"
// @Failure 400 {object} util.ResponseError "请求参数错误"
// @Failure 502 {object} util.ResponseError "错误网关"
// @Router /v1/jen/log/{job}/{id} [get]
func (*JenApi) GetBuildLog(c *gin.Context) {
	var req BuildLogRequest
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(400, gin.H{"error": "参数错误: " + err.Error()})
		return
	}
	log, err := service.AppJenServiceImp.GetJobLog(req.JobName, req.BuildID, req.Parent1, req.Parent2)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, gin.H{"data": log})
}

// GetStreamBuildLog godoc
// @Summary 流式获取 jencli 构建日志
// @Description 持续获取 jencli 构建日志
// @Param job_name query string true "Job 名称"
// @Param build_number query int true "构建编号"
// @Success 200 {string} string "成功返回构建日志"
// @Failure 400 {object} util.ResponseError "请求参数错误"
// @Failure 424 {object} util.ResponseError "依赖失败"
// @Router /v1/jen/slog/{job}/{id} [get]
func (*JenApi) GetStreamBuildLog(c *gin.Context) {
	var req BuildLogRequest
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(400, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 创建两个通道，一个用于传输日志，一个用于传输错误
	logChan := make(chan string)
	errChan := make(chan error)
	logSet := make(map[string]bool) // 用于存储已输出的日志
	var mu sync.Mutex               // 添加一个互斥锁
	service.AppJenServiceImp.GetStreamLog(c, req.JobName, req.BuildID, logChan, errChan, req.Parent1, req.Parent2)
	c.Header("Content-Type", "text/event-stream; charset=utf-8")
	c.Header("Cache-Control", "no-cache")
	c.Header("Connection", "keep-alive")

	// 使用 Gin 的 Stream 方法来处理流式响应
	c.Stream(func(w io.Writer) bool {
		for {
			select {
			case log := <-logChan:
				mu.Lock() // 加锁
				// 将日志写入响应流
				if _, exists := logSet[log]; !exists { // 检查日志是否已存在
					_, err := w.Write([]byte(log))
					if err != nil {
						mu.Unlock()  // 解锁
						return false // 如果写入失败，结束处理
					}
					c.Writer.Flush()
					logSet[log] = true // 记录已输出的日志
				}
				mu.Unlock() // 解锁
			case err := <-errChan:
				if err != nil {
					c.Error(err) // 处理错误
				}
				return false // 返回 false 结束处理
			}
		}
	})
}
